/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package PlayerComponent;

import Dispays.DeviceRecord;
import Dispays.DisplayManager;
import PlayerShell.JMplayerLoader;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;

/**
 *
 * @author wcss
 */
public class JMediaPlayer extends javax.swing.JPanel implements JPlayerResponse, Runnable {

    public DeviceRecord currentPlay = null;
    protected PlayerFrame parentForm = null;
    private boolean paused = false;
//    private boolean outputAllowed = false;
    private Boolean wantGetProgress = false;
    public int currentPlayProgress = 0;
    public JPlayerReport playerEvents = null;
    private Boolean isRunListener = false;
    private Thread playThread = null;
    private Boolean isSeeking = false;
    private int seekingvalue = 0;
    private Boolean wantGetSoundChanel = false;
    public String soundChanel = "";
    private Boolean isSeekingBefore = false;
    private Boolean wantGetTimeLength = false;
    private Boolean wantGetTimePos = false;
    public double movieTimeLength = 0;
    public double movieTimePos = 0;
    private java.io.PrintStream playerCmdStream = null;
    public String currentMovieFile = "";
    
    /**
     * Creates new form JMediaPlayer
     */
    public JMediaPlayer() {
        initComponents();
    }

    public void sendPlayerCmd(String playcmd) {
        if (currentPlay != null) {
            try 
            {
                if (playerCmdStream == null)
                {
                    playerCmdStream = new java.io.PrintStream(this.currentPlay.playerProcess.getOutputStream());
                }
                playerCmdStream.print(playcmd);
                playerCmdStream.flush();
                System.out.println("PlayerCmd:" + playcmd);
                //s.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    public void writePlayerConfigs() {
        try {
            String workDir = JAppToolKit.JRunHelper.getUserHomeDirPath() + "/.mplayer";
            File master = new File(workDir);
            if (master.exists()) {
                System.out.println("MPlayer 配置目录已存在！");
            } else {
                master.mkdirs();
            }

            //写conf文件
            ArrayList confs = new ArrayList();
            confs.add("zoom=yes");
            JAppToolKit.JDataHelper.writeAllLines(workDir + "/conf", confs);

            //写config文件
            ArrayList configs = new ArrayList();
            configs.add("# Write your default config options here!");
            configs.add("autosync=0 #解决FLV播放同步问题");
            configs.add("mc=0 #解决FLV播放同步问题");
            configs.add("ao=alsa #音频驱动选择");
            configs.add("vo=xv  #视频驱动选择");
            configs.add("stop-xscreensaver=yes #不允许播放视频时出现屏保");
            configs.add("monitoraspect=1024:768 #识别桌面分辨率为1024×768");
            configs.add("zoom=yes  #允许视频缩放");
            configs.add("subfont-autoscale=1 #设置按什么方法来进行自动缩放字幕，0－不自动缩放，1－按>    电影高度缩放，2－按电影宽度缩放，3－按电影对角线缩放(默认值)");
            configs.add("subfont-text-scale=5 #设置字幕文本的自动缩放系数(屏幕尺寸的百分比)，值范围为 0～100，默认值为5");
            configs.add("subfont-osd-scale=8 #OSD字幕的自动缩放系统(屏幕尺寸的百分比)，值范围为0～100，默认值为6");
            configs.add("font=/usr/share/fonts/truetype/wqy/wqy-microhei.ttc #设置字幕使用字体为宋体");
            configs.add("overlapsub=1 #支持多语言字幕");
            configs.add("framedrop=yes #允许掉帧<可以解决RMVB快进后声音字幕不同步的问题>");
            configs.add("sub-fuzziness=1 #设定字幕自动加载的识别，播放时可以通过j键切换");
            configs.add("cache = 8192 #此选项指定用多少内存(以kBytes为单位)作为播放文件或URL的预 缓冲");
            configs.add("fs=no");
            configs.add("quiet=no");
            configs.add("autoq=6");
            configs.add("vf=\"pp=hb:y/vb:y/ha:y:128:7/va:y/dr:y/al/,expand=0:-50:0:0\"");
            configs.add("#上面一行里面, PP是postprocess的意思,如果你的CPU足够好,那就打开这个功能,据说能提高画质.不过我没怎么看出来. Expand是在画面的下面搞出来黑条,用来放字幕,这样字幕就不会挡在画面里面了");
            configs.add("priority=abovenormal");
            configs.add("#设置MPlayer的CPU优先级,高一点的话能保证不卡");
            configs.add("#really-quiet=y");
            configs.add("benchmark=y");
            configs.add("ass=y");
            configs.add("ass-font-scale=2");
            configs.add("ass-use-margins=y");
            configs.add("ffactor=1");
            configs.add("#osdlevel=0");
            configs.add("spuaa=3");
            configs.add("dr=y");
            JAppToolKit.JDataHelper.writeAllLines(workDir + "/config", configs);
        } catch (Exception ex) {
            Logger.getLogger(JMediaPlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void playMovie(PlayerFrame parents, String moviepath) throws Exception {
        this.parentForm = parents;
//        videoWindowShow = false;

        if (currentPlay != null)
        {
            this.stopPlay();
        }
        
        playerCmdStream = null;
        currentMovieFile = moviepath;
        
        if (currentPlay == null) 
        {
            currentPlay = DisplayManager.makeVideoDevicePanel((int) this.getLocationOnScreen().getX(), (int) this.getLocationOnScreen().getY(), this.getWidth(), this.getHeight());
            DisplayManager.showVideoWindow();
            this.parentForm.videoDevice = currentPlay;
            this.parentForm.videoLocalComponent = this;
            this.parentForm.bindVideoComponent();
            
            currentPlay.playerProcess = JMplayerLoader.openPlayer(new File(moviepath), currentPlay.embeddedHandle, this.getWidth());
            isRunListener = true;
            playThread = new Thread(this);
            playThread.setDaemon(true);
            playThread.start();
            this.reportPlayAction("play");
        } else {
            throw new Exception("stop current play,please!");
        }
    }

    public void stopPlay() {
        if (currentPlay != null) {
            try {
                currentPlay.playerProcess.destroy();
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            try {
                DisplayManager.closeAll();
            } catch (Exception ex) {
                ex.printStackTrace();
            }

        }
        currentPlayProgress = 0;
        isRunListener = false;
        currentPlay = null;
        if (this.parentForm != null)
        {
           this.parentForm.removeVideoComponentListener();
        }
        this.reportPlayAction("stop");
        try {
            playThread.stop();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void pausePlay() {

        sendPlayerCmd("pause\n");
        paused = !paused;
        this.reportPlayAction("pause");
    }

    public void mutePlay() {

        if (paused) {
            sendPlayerCmd("pausing mute\n");
        } else {
            sendPlayerCmd("mute\n");
        }
        this.reportPlayAction("mute");
    }

    public void seekPlay(int playPosPercent) {

        if (currentPlay != null) {
            seekingvalue = playPosPercent;
            isSeeking = true;
            if (seekingvalue > currentPlayProgress) {
                isSeekingBefore = false;
            } else {
                isSeekingBefore = true;
            }
            String command = "seek " + playPosPercent + " 1\n";
            System.out.print(command);
            sendPlayerCmd(command);
            this.reportPlayAction("seek");
            System.out.println("seeking " + seekingvalue);
        }
    }

    public void getPlayPercent() {
        sendPlayerCmd("get_percent_pos\n");
        wantGetProgress = true;
    }

    public void getTimeLength() {
        sendPlayerCmd("get_time_length\n");
        this.reportPlayAction("get_time_length");
    }

    public void getTimePos() {
        sendPlayerCmd("get_time_pos\n");
        this.reportPlayAction("get_time_pos");
    }

//    public void fullScreenPlay() throws Exception
//    {
//        if (currentMovieFile != null)
//        {
//           if (currentMovieFile.isEmpty())
//           {
//               //为空不播放
//           }else
//           {
//              this.stopPlay();
//              FullScreenPlayerFrame fullscreen = new FullScreenPlayerFrame();
//              fullscreen.setVisible(true);
//              fullscreen.getPlayer().playMovie(fullscreen, currentMovieFile);
//              //fullscreen.getPlayer().seekPlay(seekingvalue);
//           }
//        }else
//        {
//            //为空不能播放   
//        }        
//    }
    
    public void getSoundChanel() {
        wantGetSoundChanel = true;
        sendPlayerCmd("get_audio_samples\n");
        this.reportPlayAction("getSoundChanel");
    }

    public void moveVolumeToUp() {
        sendPlayerCmd("volume 10 \n");
        this.reportPlayAction("volume+");
    }

    public void moveVolumeToDown() {
        sendPlayerCmd("volume -10 \n");
        this.reportPlayAction("volume-");
    }

    public void jumpVolumeToUp(int step)
    {
        int volume = 0;
        for(int k = 0;k < step;k++)
        {
            sendPlayerCmd("volume " + "10" + " \n");
        }        
        this.reportPlayAction("volume ++");
    }

    public void jumpVolumeToDown(int step) 
    {
        int volume = 0;
        for(int k = 0;k < step;k++)
        {
            sendPlayerCmd("volume " + "-10" + " \n");
        }        
        this.reportPlayAction("volume--");
    }    
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        setBackground(java.awt.Color.black);

        jLabel1.setFont(new java.awt.Font("DejaVu Sans YuanTi", 0, 48)); // NOI18N
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("MPlayer for Java Swing");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(38, 38, 38)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 596, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(41, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(54, 54, 54)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 361, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(50, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    // End of variables declaration//GEN-END:variables

    protected void reportPlayProgress(int percent) {
        if (playerEvents != null) {
            this.playerEvents.reportPlayProgress(this, percent);
        }
//        if (videoWindowShow) {
//            //已显示
//        } else {
//            videoWindowShow = true;
//            DisplayManager.showVideoWindow();
//        }
    }

    protected void reportPlayAction(String action) {
        if (playerEvents != null) {
            playerEvents.reportPlayAction(this, action);
        }
    }

    @Override
    public void responseContent(String content, Boolean isErrorText) {
        if (wantGetProgress) {
            wantGetProgress = false;
            if (content.contains("ANS_PERCENT_POSITION=")) {
                currentPlayProgress = Integer.parseInt(content.replace("ANS_PERCENT_POSITION=", ""));
                System.out.println("播放进度：" + currentPlayProgress + "%");
            }
        } else if (wantGetTimeLength) {
            wantGetTimeLength = false;
            if (content.contains("ANS_LENGTH=")) {
                movieTimeLength = Double.parseDouble(content.replace("ANS_LENGTH=", ""));
                System.out.println("影片长度：" + movieTimeLength + "秒");
                reportPlayAction("ShowTimeLength");
            }

        } else if (wantGetTimePos) {
            wantGetTimePos = false;
            if (content.contains("ANS_TIME_POSITION=")) {
                movieTimePos = Double.parseDouble(content.replace("ANS_TIME_POSITION=", ""));
                System.out.println("影片位置：" + movieTimePos + "秒");
                reportPlayAction("ShowTimePos");
            }
        }
//        else if (wantGetSoundChanel)
//        {
//            wantGetSoundChanel = false;
//            //ANS_AUDIO_SAMPLES='44100 Hz, 2 ch.'
//            String chaneltext  = content.replace("'", "").replace("ANS_AUDIO_SAMPLES=", "");
//            String[] sounds = chaneltext.split("\\,");
//            if (sounds.length >= 2)
//            {
//               soundChanel = sounds[1].trim();
//               this.reportPlayAction("SoundChanelCount");
//            }
//        }
    }

    @Override
    public void run() {
        while (isRunListener) {
            try {
                if (paused) {
                } else {
                    System.out.println("running");
                    if (isSeeking) {
//                        if (isSeekingBefore)
//                        {
//                            if (currentPlayProgress < seekingvalue + 5)
//                            {
//                                isSeeking = false;
//                            }else
//                            {
//                                seekPlay(seekingvalue);
//                            }
//                        }else
//                        {
//                            if (currentPlayProgress >= seekingvalue)
//                            {
//                               isSeeking = false; 
//                            }else
//                            {
//                               seekPlay(seekingvalue);
//                            }
//                        }
                        isSeeking = false;
                    } else {
                        reportPlayProgress(currentPlayProgress);
                    }

                    if (currentPlayProgress >= 100) {
                        SwingUtilities.invokeLater(new Runnable() {

                            public void run() {
                                pausePlay();
                                DisplayManager.hideCurrentDevice();
                            }
                        });
                    }
                    this.getPlayPercent();
                }
                Thread.sleep(3000);
            } catch (InterruptedException ex) {
                Logger.getLogger(JMediaPlayer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
